
import { App, Adapter, Shaders, BitMath } from "../lib.letusbit/lib"
import { Renderer, Render_Texture, ShaderResources } from "../lib.letusbit/renderer/adapter";

export class myloop implements App.IUserCode {
    //这个适配器的设计可能有点扯蛋了，前面不知道哪里脑抽，要考虑兼容一个2D的渲染器
    //彻底无此必要，基于Webgl SpriteRenderer 和LUT表做一个渲染器即可，shader也是少量有限个

    //后面简化适配器设计，删除2d支持
    //另外由于Texture有通道的概念，把这个概念抽出来，
    //最常见的是RGBA 四通道贴图，实际上贴图格式 可以是 1~4通道 ， 我们可以分别控制使用几个通道，以及这些通道的功能
    // RGBA R8 RGB 是最常见的传统通道
    // 我们还可以扩展出 CUVA ，一个通道传递colorindex，可以查表出正色，两个通道保存法线，做特殊光照或者别的信息，一个通道保存alpha啥的
    // 由于NES有世界调色板的存在，世界调色板不会超出256色，所以我们不应该使用RGBA这种格式
    // 故而 我们只需要使用 1 通道 贴图 和 4通道贴图
    // 1通道贴图就是index
    // 4通道贴图固定r通道是index，其它三个自选，配合材质使用
    batcher?: Renderer.SpriteBatcher;
    bufrect: Renderer.SpritePoint[] = [
        { x: 0, y: 0, z: 0, r: 1, g: 1, b: 1, a: 1, u: 0, v: 0 },
        { x: 256, y: 0, z: 0, r: 1, g: 1, b: 1, a: 1, u: 1, v: 0 },
        { x: 0, y: 32, z: 0, r: 1, g: 1, b: 1, a: 1, u: 0, v: 1 },
        { x: 256, y: 32, z: 0, r: 1, g: 1, b: 1, a: 1, u: 1, v: 1 },
    ];
    addTexture(rect: BitMath.Rect, mat: Renderer.Material): void {
        this.bufrect[0].x = rect.x;
        this.bufrect[0].y = rect.y;
        this.bufrect[1].x = rect.x + rect.w;
        this.bufrect[1].y = rect.y;
        this.bufrect[2].x = rect.x;
        this.bufrect[2].y = rect.y + rect.h;
        this.bufrect[3].x = rect.x + rect.w;
        this.bufrect[3].y = rect.y + rect.h;
        this.batcher?.SetMat(mat);
        this.batcher?.addRect(this.bufrect);
        //this.batcher?.Render();
    }


    mat: Renderer.Material = new Renderer.Material();
    mat2: Renderer.Material = new Renderer.Material();
    matlutrgb: Renderer.Material = new Renderer.Material();
    matlutquick: Renderer.Material = new Renderer.Material();
    matlutslow: Renderer.Material = new Renderer.Material();
    matrt: Renderer.Material = new Renderer.Material();
    t0?: Render_Texture.RenderTarget;
    async OnInit(app: App.IFramework): Promise<void> {
        var prog = Shaders.GetShaderProgram("default");
        if (prog != null) {
            console.log("got shader default succ.");
        }
        this.batcher = app.render.CreateBatcher();


        this.mat.shader = Shaders.GetShaderProgram("default");
        this.mat.texMain = app.render.worldTexPalette;


        this.mat2.shader = Shaders.GetShaderProgram("palette");
        let tex2 = new Render_Texture.Texture(app.render.webgl, Render_Texture.TextureFormat.GRAY);
        this.mat2.texMain = tex2;
        var data = new Uint8Array(256);
        for (var i = 0; i < data.length; i++)
            data[i] = i;

        tex2.loadimgFromData(data, 16, 16, false, false);


        //show lutrgb
        this.matlutrgb.shader = Shaders.GetShaderProgram("palette");
        let texlutrgb = new Render_Texture.Texture(app.render.webgl, Render_Texture.TextureFormat.GRAY);

        this.matlutrgb.texMain = texlutrgb;
        let _pal = BitMath.Palette.CreateDefault();
        let _buf = new Uint8Array(65536);
        Renderer.RenderWebgl.ParseLUTRGB(_pal, _buf, texlutrgb);


        //show worldtexlut
        this.matlutquick.shader = Shaders.GetShaderProgram("palette");
        this.matlutquick.texMain = app.render.worldTexLUT;
        Renderer.RenderWebgl.ParseLUTLABQuick_Worker(_pal, _buf, app.render.worldTexLUT);

        //show slow lut
        this.matlutslow.shader = Shaders.GetShaderProgram("default");
        let texlutslow = new Render_Texture.Texture(app.render.webgl, Render_Texture.TextureFormat.GRAY);
        this.matlutslow.texMain = texlutslow;
        //這玩意真的slow，所以最好還是離綫處理，算完存下來
        Renderer.RenderWebgl.ParseLUTLABSlow_Worker(_pal, _buf, texlutslow);


        let target = new Render_Texture.RenderTarget(app.render.webgl, 1024, 64);
        this.matrt.shader=Shaders.GetShaderProgram("default");
        this.matrt.texMain = target;
        this.t0=target;
    }
    OnUpdate(app: App.IFramework): void {

        if (this.t0) {
            app.render.BeginTarget(this.t0);
            this.addTexture(new BitMath.Rect(0, 0, 1024, 64), this.matlutquick);
            this.batcher?.Render();
            app.render.EndTarget();
        }

        app.render.Begin();
        this.addTexture(new BitMath.Rect(0, 0, 1024, 64), this.matlutrgb);
        this.addTexture(new BitMath.Rect(0, 0, 256, 4), this.mat);
        this.addTexture(new BitMath.Rect(32, 32, 64, 64), this.mat2);
        this.addTexture(new BitMath.Rect(0, 128, 1024, 64), this.matrt);
        this.addTexture(new BitMath.Rect(0, 196, 1024, 64), this.matlutquick);
        this.addTexture(new BitMath.Rect(0, 264, 1024, 64), this.matlutslow);
        this.batcher?.Render();
        app.render.End();
    }
    OnResize(app: App.IFramework): void {

    }
}
